
attribute vec4 Position;
attribute vec2 TexCoords;
attribute vec4 Normal;

uniform mat4 ProjectionMatrix;
uniform mat4 ModelViewMatrix;

// SHADOW
uniform mat4 DepthTextureMatrix;

uniform vec4 MaterialDiffuseColor;

struct Light
{
	vec4 position;
	vec3 diffuseColor;
	float radius;
};
uniform Light light;

varying vec2 fs_TexCoords;
varying vec3 EyeSpaceNormal;
varying vec3 LightDirection;
varying vec4 LightDiffuseColor;
varying vec4 VertexColor;

// SHADOW
varying vec4 ShadowCoords;

void main()
{	
	// Idealement il faudrait passer une autre matrice 3x3 en tant qu'uniform.
	// Les normales doivent en effet etre transformee par la transposee de l'inverse 
	// de la matrice utilisee pour transformer les vertices. On gagne ainsi quelques instructions.
	// Lorsque cette derniere est orthogonale [M^-1]^T = M, ce que l'on exploite ici.
	//
	// note: on pourrait aussi faire le lighting dans le repere objet (en amenant la lumiere dans ce repere)
	// cela dit pour une point light ou un spot le fall off serait un peu plus complexe
	// 
	vec4 Nrm = vec4(Normal.xyz, 0);
	EyeSpaceNormal = (ModelViewMatrix * Nrm).xyz;	
	
	// Les calculs se font dans le repere de la camera il faut donc aussi une position de vertex dans ce repere
	vec4 ModelViewPosition = ModelViewMatrix * Position;

	// mix(x,y,a) interpole lineairement les valeurs x et y par le poids a: x*(1-a) + y*a
	// on va ainsi autoconfigurer le calcul de la direction de la lumiere en evitant un test if
	//
	// light.position.w = 0 -> lumiere directionnelle sinon -> point light. 
	
	LightDirection = mix(light.position.xyz, (light.position.xyz - ModelViewPosition.xyz), light.position.w);
	
	// Etant donne que l'on va de toute facon normaliser LightDirection a chaque fragment autant ne pas le faire ici
	//LightDirection = normalize(LightDirection);

	LightDiffuseColor = vec4(light.diffuseColor, 1.0);
	
	fs_TexCoords = TexCoords;
	VertexColor = MaterialDiffuseColor;	

	// SHADOW
	ShadowCoords = DepthTextureMatrix * Position;

	gl_Position = ProjectionMatrix * ModelViewMatrix * Position;
}